package top.lixunda.common.validate.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * @author Xumda
 * @version time:2019/12/23 13:03
 */
@SuppressWarnings("SpringFacetCodeInspection")
@Component
@Slf4j
@Aspect
@Configuration
public class XumValidateAspect {

    private static final XumValidateAspectExecutor EXECUTOR = new XumValidateAspectExecutor();

    public XumValidateAspect() {
        log.info(">>>>>>>>>>>>>>>>> XumValidateAspect <<<<<<<<<<<<<<<<<<");
    }

    /**
     * 带有注解表示是一个请求的方法
     */
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PutMapping) ||" +
            "@annotation(org.springframework.web.bind.annotation.DeleteMapping) ||" +
            "@annotation(org.springframework.web.bind.annotation.PatchMapping)")
    public void pointCut0() {
    }

    /**
     * 当GetMapping等注解可能存在父类中时，只能通过RestController进行判断
     */
    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    public void pointCut1() {

    }

    /**
     * 至少包含一个参数
     */
    @Pointcut("!args()")
    public void pointCut2() {

    }

    /**
     * 合并方法上GetMapping等注解和类上RestController注解
     */
    @Pointcut("pointCut0() || pointCut1()")
    public void pointCut3() {

    }

    /**
     * 请求的类都是公共方法
     */
    @Pointcut("execution(public * *(..))")
    public void pointCut4() {

    }

    @Around("pointCut3() && pointCut2() && pointCut4()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        return EXECUTOR.around(proceedingJoinPoint);
    }
}
